fix(openapi): declare the predictedGate/dataQuality fields branch-analysis actually returns (#9531) - #9587
Conversation
…lysis actually returns (#9531) POST /v1/local/branch-analysis returns `{ ...analysis, predictedGate, dataQuality }`, and LocalBranchAnalysisSchema declared neither -- the spec-vs-payload defect #9531 named in advance. The retired key-set diff could never have caught it: it only ever looked at the two settings schemas. PredictedGateVerdictSchema (#9517) is authored here and pinned to PredictedGateVerdict by the same compile-time assertion, which now covers three schemas. dataQuality uses the opaque record shape every other schema in this file already models it with. confirmedContributor becomes optional on PredictedGateVerdict rather than required-and- possibly-undefined: buildPredictedGateVerdict forces it to undefined under the oss-anti-slop pack, so JSON.stringify drops the key outright and a client reading the spec sees an absent field, not a null one. The contributor skill's CI tables named ui:openapi:settings-parity as a distinct check; both entries now point at typecheck, which is where the parity failure surfaces.
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-28 20:14:03 UTC
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
📋 Copy for AI agents — paste into your coding agentDecision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | 4dac031 | Commit Preview URL Branch Preview URL |
Jul 28 2026, 07:53 PM |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9587 +/- ##
==========================================
- Coverage 89.83% 89.83% -0.01%
==========================================
Files 878 878
Lines 111040 111047 +7
Branches 26435 26435
==========================================
+ Hits 99756 99759 +3
Misses 9992 9992
- Partials 1292 1296 +4
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Bundle ReportChanges will increase total bundle size by 4.69kB (0.06%) ⬆️. This is within the configured threshold ✅ Detailed changes
Affected Assets, Files, and Routes:view changes for bundle: loopover-uiAssets Changed:
|


Summary
Follow-up to #9585, which the gate merged while this was in progress. That PR retired
scripts/check-openapi-settings-parity.tsand replaced it with a compile-time schema↔type assertion; this one applies the same mechanism to the one spec-vs-payload defect #9531 named in advance, and closes the loose ends #9585 left.LocalBranchAnalysisSchemadeclared neitherpredictedGatenordataQuality, butPOST /v1/local/branch-analysisreturns{ ...analysis, predictedGate, dataQuality }(src/api/routes.ts). A client generated from the published spec had no way to know about the entire pre-submission gate prediction — the most useful field on the response. The retired key-set diff could never have caught this: it only ever looked atRepositorySettingsandRepoSettingsPreview.PredictedGateVerdictSchemais authored here (the contract: create @loopover/contract — the single zod source for tool/API schemas, with a six-tool pilot #9517 schema api: drive the route↔spec ratchet to zero — migrate every route through the seam, retire the parallel security model #9531 called for) and pinned toPredictedGateVerdictby the same exact-equality assertion, which now covers three schemas instead of two.dataQualityuses the opaque record shape every other schema in the file already models it with, rather than inventing a preciseDataQualityschema — that is its own change.confirmedContributorbecomes optional onPredictedGateVerdictrather than required-and-possibly-undefined.buildPredictedGateVerdictdeliberately forces it toundefinedunder theoss-anti-sloppack, where confirmed status carries no meaning, soJSON.stringifydrops the key outright and a client reading the spec sees an absent field, not a null one. Same reasoning asRepoSettingsPreview.autoProjectMilestoneMatchin refactor(openapi): replace the settings-parity script with a compile-time schema/type assertion (#9531) #9585.openapi-settings-schema-parity→openapi-schema-type-parity, since it no longer covers only the settings schemas.ui:openapi:settings-parityas a distinct check after refactor(openapi): replace the settings-parity script with a compile-time schema/type assertion (#9531) #9585 deleted it; both entries now point attypecheck, which is where a parity failure actually surfaces.Six published-spec defects have now been fixed under this mechanism: the dead
autonomylevels (#4620), the missingcontributorBlacklist.githubId(#9125),moderationRules' missingcopycatmember (#1969),expectedCiContexts' undeclared null, the settings-preview's unreachableaiReviewConfirmedContributorsOnlynull, and this PR'spredictedGate/dataQuality.Part of #9531.
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
npm audit --audit-level=moderatereports 11 pre-existing high-severity advisories from thewrangler→miniflaretransitive chain underpackages/discovery-index. This PR changes no dependency and does not touchpackage-lock.json, so the result is identical onmain; bumping that chain is a separate change and does not belong in a spec-parity PR.test:engine-parity,engine-parity:drift-check, the@loopover/engineworkspace test run,dead-source-files:check,import-specifiers:check,docs:drift-check.coverage/lcov.infodirectly: 0 uncovered and 0 partially-covered changed lines across every changed file. Fulltest/unit+test/contractrun: 23,578 passed, 6 skipped.Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.UI Evidence
Not applicable — no visible UI, frontend, or docs change. The only
apps/loopover-ui/**file touched is the generatedpublic/openapi.json.Notes
predictedGateprediction is built from the repo's public.loopover.ymlonly, never the maintainer's private DB settings, so declaring it in the published spec exposes nothing a contributor could not already read from the repo.PredictedGateVerdictSchemais registered as its own named component (#/components/schemas/PredictedGateVerdict) rather than inlined, so orb(mcp): ORB management tool family — instance doctor/status/logs, queue+kill-switch ops, fleet + hosted-tenant administration #9522's management tooling and any spec-derived client get a reusable type.